<template>
  <div id="qcMaterialResultDiv">
    <Breadcrumb content="结果录入(按项目)" />
    <div class="bodyContent">
      <Splitpanes>
        <Pane size="30">
          <!-- 质控靶值设定  -->
          <div class="saveBtn">
            <vxe-checkbox v-model="searchForm.isShowAll" size="small" content="显示过期的质控品" checked-value="1" unchecked-value="0" @change="findMaterialItemTree"></vxe-checkbox>
          </div>
          <vxe-toolbar perfect>
            <template #buttons>
              <div class="smallToolTitle">仪器</div>
              <vxe-select v-model="searchForm.instrIds" multiple :filterable="true" clearable @change="valueChangeEvent">
                <vxe-option v-for="instr in instrList" :key="instr.id" :value="instr.id" :label="instr.instrName"></vxe-option>
              </vxe-select>
              <vxe-button type="text" class="button-blue" icon="vxe-icon-refresh" content="刷新" :loading="treeloading" @click="findMaterialItemTree"></vxe-button>
            </template>
          </vxe-toolbar>
          <el-scrollbar style="height: calc(100% - 40px)">
            <div class="sampleType">
              <el-scrollbar>
                <el-tree :expand-on-click-node="false" :default-expanded-keys="expandedkeys" :data="materialItemTree" :props="defaultProps" node-key="id" ref="materialItemTreeRef" highlight-current class="tools-tree" @node-click="handleClickType" v-loading="treeloading">
                  <template #default="{ data, node }">
                    <div style="float: right">
                      <img :src="`${getAssetsFile('images/qc/' + data.type + '.png')}`" style="width: 15px; height: 15px; margin-right: 10px" />
                      {{ data.name }}
                    </div>
                  </template>
                </el-tree>
              </el-scrollbar>
            </div>
          </el-scrollbar>
        </Pane>
        <Pane size="70">
          <vxe-toolbar perfect>
            <template #buttons>
              <div class="smallToolTitle">结果录入</div>
              <vxe-input v-model="resultSearchForm.qcDate" placeholder="选择月份" type="month" valueFormat="yyyy-MM-dd" :disabled="disabledTag" @change="findMaterialResultList"></vxe-input>

              <vxe-button type="text" class="button-blue" icon="vxe-icon-save" content="保存" :disabled="disabledTag" @click="saveIQCResult"></vxe-button>
              <vxe-button type="text" class="button-blue" icon="vxe-icon-refresh" content="刷新" :disabled="disabledTag" :loading="rloading" @click="findMaterialResultList"></vxe-button>
            </template>
          </vxe-toolbar>
          <div class="tableBox">
            <vxe-table ref="materialResultTableRef" v-loading="rloading" class="result-table mytable-scrollbar" border resizable show-overflow :data="dayResults" :edit-config="{
                trigger: 'click',
                mode: 'cell'
              }" height="auto" :menu-config="tableMenu" @menu-click="contextMenuClickEvent" @cell-click="cellClickEvent" :mouse-config="{ selected: true }" :keyboard-config="{
                isArrow: true,
                isTab: true,
                isEdit: true
              }">
              <vxe-column field="day" title="日期" width="40" align="center"></vxe-column>

              <vxe-column :title="'次数' + i" :field="'result' + i" min-width="100" v-for="i in dayNum" :key="i" header-align="center" :edit-render="{
                  autofocus: '.vxe-input--inner',
                  autoselect: true
                }" class-name="number-right">
                <template #default="{ row }">
                  <div :class="[
                      row.sequenceResults[i - 1].z >= 3
                        ? 'zS3'
                        : row.sequenceResults[i - 1].z >= 2
                        ? 'zS2'
                        : '',
                      row.sequenceResults[i - 1].z <= -3
                        ? 'zS-3'
                        : row.sequenceResults[i - 1].z <= -2
                        ? 'zS-2'
                        : ''
                    ]">
                    <i :class="
                        row.sequenceResults[i - 1].isOutControl
                          ? 'el-icon-warning'
                          : row.sequenceResults[i - 1].isAlarm
                          ? 'el-icon-warning-outline'
                          : row.sequenceResults[i - 1].isBestInDay
                          ? 'el-icon-success'
                          : ''
                      "></i>
                    <span>{{ row.sequenceResults[i - 1].result }}</span>
                  </div>
                </template>
                <template #edit="{ row, $rowIndex, column }">
                  <vxe-input :ref="'result' + $rowIndex" v-model="row.sequenceResults[i - 1].result" @input="originalResultChange(row, i)" :disabled="disabledTag" @change="
                      IQCResultChange(row, row.sequenceResults[i - 1].result, $rowIndex, index)
                    " @keydown.native.enter="resultEnterEvent(row, index, $rowIndex, i, column)"></vxe-input>
                </template>
              </vxe-column>

              <vxe-column field="meanValue" title="当天均值" min-width="100" header-align="center" class-name="number-right"></vxe-column>
              <vxe-column field="mean" title="靶值" min-width="100" header-align="center" class-name="number-right">
                <template #default="{ row }">
                  {{ row.sequenceResults[0] ? row.sequenceResults[0].mean : '' }}
                </template>
              </vxe-column>
              <vxe-column field="sd" title="SD" min-width="100" header-align="center" class-name="number-right">
                <template #default="{ row }">
                  {{ row.sequenceResults[0] ? row.sequenceResults[0].sd : '' }}
                </template>
              </vxe-column>
              <vxe-column title="确认人" width="100" header-align="center">
                <template slot-scope="scope">
                  <!-- {{ scope.row.person ? scope.row.person.name : '' }} -->
                  ewewe
                </template>
              </vxe-column>
            </vxe-table>
          </div>
        </Pane>
      </Splitpanes>
    </div>

    <!-- 失控记录抽屉 -->
    <el-drawer v-model="showDrawer" show-close title="失控记录" :with-header="false" modal-class="drawerBulkModal" direction="rtl" :size="'calc(100vw - ' + 70 + 'px)'" :modal="false" append-to-body>
      <GoBack :content="materialItemTree.id ? '编辑' : '新建'" :backUrl="'/qcmaterialresult'" @click.native="clearDrawer" />
      <div class="iqcOutControl">
        <QcOutControlRecChart ref="qcOutControlRecChartRef" />
      </div>
    </el-drawer>
  </div>
</template>
<script setup lang="ts">
// 引入组件区 ==========
import { ref, reactive, getCurrentInstance, onMounted } from 'vue';
import Breadcrumb from '@/components/Breadcrumb.vue';
import moment from 'moment';
import { Splitpanes, Pane } from 'splitpanes';
import { VxeMessage, VxeNotifyType } from '@/utils/CommonMessage'; //提示框
import { DateToString, formatDateTime, getAssetsFile } from '@/utils/common';
import { AppStore } from '@/stores/store';
import { isEmpty } from 'lodash';
import QcOutControlRecChart from '@/views/lab_sys/qc_set/QcOutControlRecChart.vue'; //失控记录图表
import GoBack from '@/components/GoBack.vue'; //返回组件

// 全局变量定义区 ==========
let store = AppStore();
let { proxy }: any = getCurrentInstance();
// 加载状态
let treeloading = ref(false); //质控靶值树上的刷新
let rloading = ref(false);
let showDrawer = ref(false);
let disabledTag = ref(true);
let materialItemTree: any = reactive([]); //最左侧质控靶值设定树数据
let instrList: any = reactive([]); //左侧仪器下拉项
let expandedkeys: any = reactive([]);
let dayResults: any = reactive([]); //质控项目设定表格数据
let dayNum = 7; //每天质控次数
let qcDays = 0; //每月质控天数
let places = 0; //质控结果保留的小数位
// 质控结果原值
let originalResult = '';
// 最左侧的树
let defaultProps = {
  children: 'children',
  label: 'name'
};
let sltMaterItem: any = reactive({}); //最左侧树选中行
let currentCellIQCResult: any = reactive({});
let qcOutControlRecChartRef: any = ref(null);
let qcResultId = ref(null);
let searchForm = ref({
  searchValue: '',
  instrId: '',
  instrIds: [],
  isShowAll: '0'
});
let resultSearchForm = ref({
  searchValue: '',
  qcDate: DateToString(new Date())
});

// 方法定义区 =============
// 页面加载时更新
onMounted(() => {
  findInstrSetupList();
  findMaterialItemTree(); // 获取最左侧质控靶值树数据
});

// 获取左侧仪器下拉选项数据(标题)
function findInstrSetupList() {
  instrList.length = 0; //放入数据前清空数据
  const url = '/lis/instrSetup/getInstrSetupList';
  proxy.$http
    //注意此处的数据条数
    .get(url, {
      params: { seachValue: '', poct: 1 }
    })
    .then((res: any) => {
      instrList.push(...res.data);
    })
    .catch((err: any) => {
      VxeMessage('获取左侧仪器表格数据异常', VxeNotifyType.error);
    });
}

// 仪器下拉选择 改变
function valueChangeEvent() {
  findMaterialItemTree();
}

// 获取最左侧质控靶值树 刷新
function findMaterialItemTree() {
  treeloading.value = true;
  materialItemTree.length = 0; //放入数据前清空数据
  expandedkeys.length = 0;
  sltMaterItem = reactive({});
  const url = '/api/qc/qcMaterialItem/findMaterialItemTree';
  proxy.$http
    //注意此处的数据条数
    .get(url, { params: { isShowAll: searchForm.value.isShowAll, instrIds: searchForm.value.instrIds, poct: 1 } })
    .then((res: any) => {
      if (!IsEmpty(res.data)) {
        materialItemTree.push(...res.data);
        //默认选中第一条
        //如果点击的当前行数据是父级，那就禁用质控品维护的按钮
        // const sltObj = getChildren(materialItemTree[0]);
        // // 光标定位在字典分类列表的第一项
        // setCurTypeNode(sltObj.id);
        // if (sltObj.isSearch == '0') {
        //   sltMaterItem = sltObj;
        // }
        // findMaterialResultList();

        getExpandedkeys();
        if (!sltMaterItem.id) {
          disabledTag.value = true;
        } else {
          //如果点击的当前行数据是子集，那就不需要禁用质控品维护的按钮
          disabledTag.value = false;
        }
      }
      treeloading.value = false;
    })
    .catch((err: any) => {
      treeloading.value = false;
      VxeMessage('获取最左侧质控靶值树异常', VxeNotifyType.error);
    });
}

//点击左侧树
function handleClickType(obj: any, node: any, data: any) {
  const isSearch = obj.isSearch;
  sltMaterItem = reactive({});
  if (isSearch == '0') {
    sltMaterItem = obj;
  }
  findMaterialResultList();
  //如果点击的当前行数据是父级，那就禁用质控品维护的按钮
  if (!sltMaterItem.id) {
    disabledTag.value = true;
  } else {
    //如果点击的当前行数据是子集，那就不需要禁用质控品维护的按钮
    disabledTag.value = false;
  }
}

// 根据日期计算天数
function countDaysByMonth() {
  const year = new Date(resultSearchForm.value.qcDate).getFullYear();
  const month = new Date(resultSearchForm.value.qcDate).getMonth() + 1;
  qcDays = new Date(year, month, 0).getDate();
}

// 获取质控靶值设定表格数据 刷新
function findMaterialResultList() {
  rloading.value = true;
  dayResults.length = 0; //放入数据前清空数据
  countDaysByMonth();
  const url = '/api/qc/qcMaterialItemResult/getQcResultByMonth';
  proxy.$http
    //注意此处的数据条数
    .get(url, {
      params: {
        pid: sltMaterItem.id,
        qcMonth: formatDateTime(new Date(resultSearchForm.value.qcDate), 'yyyy-MM')
      }
    })
    .then((res: any) => {
      // materialResultList.push(...res.data);
      // rloading.value = false;
      setIQCMaterialDate(res);
    })
    .catch((err: any) => {
      rloading.value = false;
      VxeMessage('获取右侧质控项目表格数据异常', VxeNotifyType.error);
    });
}

// 返回的数据处理
function setIQCMaterialDate(res: any) {
  const QCDate = new Date(formatDateTime(resultSearchForm.value.qcDate, 'yyyy-MM-01')).valueOf();
  places = sltMaterItem.desPos ? sltMaterItem.desPos : 0;
  const results = [];
  for (let i = 0; i < qcDays; i++) {
    // 先给每天添加符合数据类型的数据
    results.push({
      day: i + 1,
      qcDate: formatDateTime(new Date(QCDate + 24 * 60 * 60 * 1000 * i), 'yyyy-MM-dd 00:00:00'),
      sequenceResults: [] as any,
      meanValue: null //当天平均值
    });
    // 每天质控次数的数据类型
    for (let j = 0; j < dayNum; j++) {
      results[i].sequenceResults.push({
        alarmRules: '', //警报规则
        isAlarm: false, //是否警报
        isBestInDay: false, //最优结果
        isOutControl: false, //是否失控
        outControlRules: '', //失控规则
        isOutControlHandled: false, //是否失控处理
        mean: null, //均值/靶值
        qcSequence: j + 1, //质控次数
        result: '', //质控结果
        numResult: null, //质控数值结果
        sd: null, //标准差
        z: null //Z分数值
      });
    }

    if (res.data) {
      // 循环每个质控物，计算当天质控物结果平均值，小数位通过分析系统 places 确定
      res.data.forEach((item) => {
        if (item.day === i + 1) {
          let sum = 0;
          let num = 0;
          item.sequenceResults.forEach((value, index) => {
            if (!IsEmpty(value.numResult)) {
              sum += value.numResult;
              num++;
            }
            // 把预制的当天次数的相关结果，用返回值中对应次数底板数据替换
            results[i].sequenceResults[Number(value.qcSequence) - 1] = value;
          });

          item.meanValue = (sum / num).toFixed(places > -1 ? places : 2);
          // 拿到当天的时间和平均值
          results[i].qcDate = item.qcDate;
          results[i].meanValue = item.meanValue;
        }
      });
    }
  }
  dayResults = results;
  rloading.value = false;
}

function saveIQCResult() {
  const time = new Date(formatDateTime(resultSearchForm.value.qcDate, 'yyyy-MM')).valueOf();

  rloading.value = true;

  const iqcResults = [] as any[];
  for (const item of dayResults) {
    for (let i = 0; i < item.sequenceResults.length; i++) {
      iqcResults.push({
        qcDate: IsEmpty(item.qcDate) ? formatDateTime(new Date(), 'yyyy-MM-dd 00:00:00') : item.qcDate,
        qcSequence: item.sequenceResults[i].qcSequence,
        result: item.sequenceResults[i].result,
        id: item.sequenceResults[i].id,
        qcItemId: item.sequenceResults[i].qcItemId,
        instrId: item.sequenceResults[i].instrId,
        materialId: item.sequenceResults[i].materialId,
        materialItemId: item.sequenceResults[i].materialItemId,
        sd: item.sequenceResults[i].sd,
        mean: item.sequenceResults[i].mean,
        createTime: item.sequenceResults[i].createTime
      });
    }
  }
  const url = '/api/qc/qcMaterialItemResult/saveOrUpdateMaterialResult';
  const obj: any = {
    materialId: sltMaterItem.materialId,
    materialItemId: sltMaterItem.id,
    qcItemId: sltMaterItem.qcItemId,
    instrId: sltMaterItem.instrId,
    itemDictId: sltMaterItem.itemDictId,
    method: sltMaterItem.method,
    batchNum: sltMaterItem.batchNum,
    qcNo: sltMaterItem.qcNo,
    horizontal: sltMaterItem.horizontal,
    itemDefine: sltMaterItem.itemDefine,
    qcMonth: formatDateTime(new Date(resultSearchForm.value.qcDate), 'yyyy-MM')
  };
  obj.iqcResults = iqcResults;
  proxy.$http
    .post(url, obj)
    .then((res: any) => {
      rloading.value = false;
      findMaterialResultList();
      // this.findIQCMaterialResultList('', false);
      VxeMessage('保存成功', VxeNotifyType.success); //保存成功显示成功类型
    })
    .catch((res: any) => {
      rloading.value = false;
      VxeMessage('保存失败', VxeNotifyType.error);
    });
}

const tableMenu = {
  body: {
    options: [
      [
        {
          code: 'IQCOutControl',
          name: '失控处理',
          prefixIcon: 'vxe-icon-warning-circle',
          disabled: false
        }
      ]
    ]
  },
  visibleMethod: ({ options, row, columnIndex }) => {
    options.forEach((list) => {
      list.forEach((item) => {
        // 当结果中的isOutControl 为false时，禁用右键菜单中的 失控处理 IQCOutControl
        if (item.code === 'IQCOutControl') {
          currentCellIQCResult = row.sequenceResults[columnIndex - 1];
          item.disabled = !row.sequenceResults[columnIndex - 1].isOutControl;
        }
      });
    });
    // 当结果中的isOutControl 为true时，显示右键菜单
    // return row.sequenceResults[columnIndex - 1].isOutControl;
    return true;
  }
};

function contextMenuClickEvent({ menu, row, columnIndex }) {
  proxy.$nextTick(() => {
    qcResultId.value = row.sequenceResults[columnIndex - 1].id;
  });
  //proxy[menu.code]();
  if (menu.code == 'IQCOutControl') {
    IQCOutControl();
  }
}

// 单元格点击事件
function cellClickEvent({ row, column, columnIndex }) {
  if (column.field === 'result' + columnIndex) {
    currentCellIQCResult = row.sequenceResults[columnIndex - 1];
    qcResultId.value = row.sequenceResults[columnIndex - 1].id;
  }
}

// 点击右键菜单里的失控处理
function IQCOutControl() {
  showDrawer.value = true;
  proxy.$nextTick(() => {
    qcOutControlRecChartRef.value.initPage(qcResultId);
  });
}
function clearDrawer() {
  showDrawer.value = false;
}

function originalResultChange(row, i) {
  if (IsEmpty(row.sequenceResults[i - 1].result) || /^\d+(\.\d*)?$/.test(row.sequenceResults[i - 1].result.trim())) {
    return;
  }
  VxeMessage('请输入数字', VxeNotifyType.error);

  // this.$notify.error({
  //   title: '输入错误',
  //   message: '请输入数字',
  //   duration: 3000
  // });
}

/**
 * row：当前行 result：当前单元格结果 rowIndex：当前行数 tabIndex：当前质控物索引值
 */
function IQCResultChange(row, result, rowIndex, tabIndex) {
  if (originalResult === result) {
    return;
  }
  let sum = 0;
  let num = 0;
  for (let index = 0; index < dayNum; index++) {
    if (!IsEmpty(row.sequenceResults[index].result) && !IsEmpty(row.sequenceResults[index].result.trim())) {
      sum += Number(row.sequenceResults[index].result.trim());
      num++;
    }
  }
  row.meanValue = num === 0 ? '' : Number(sum / num).toFixed(places);
}

function getChildren(obj: any) {
  const children = obj.children;
  if (!IsEmpty(children) && children.length > 0) {
    return getChildren(children[0]);
  } else {
    return obj;
  }
}
// 光标定位在指定字典分类上
function setCurTypeNode(nodeId) {
  proxy.$nextTick(() => {
    const treeName = 'materialItemTreeRef';
    const tree: any = proxy.$refs[treeName];
    tree.setCurrentKey(nodeId);
  });
}
// ------------------------------------------------------------
//**判断为空*/
function IsEmpty(value: any) {
  if (value === undefined || value === '' || value === null) {
    return true;
  }
  if (JSON.stringify(value) === '{}') {
    return true;
  }
  return false;
}

function getExpandedkeys() {
  for (const materialItem of materialItemTree) {
    pusExpandedkeys(materialItem);
  }
}

function pusExpandedkeys(obj: any) {
  const children = obj.children;
  if (obj.type == 'instrClass') {
    //expandedkeys.push(obj.id);
  }
  if (!IsEmpty(children) && children.length > 0) {
    for (const ch of children) {
      pusExpandedkeys(ch);
    }
  }
}
</script>

<style lang="scss" scoped>
#qcMaterialResultDiv {
  height: 100%;
  .bodyContent {
    height: calc(100% - 60px);
    .splitpanes {
      background-color: $base-white;
      // 显示过期的质控品按钮
      .saveBtn {
        float: right;
        margin: 10px 50px;
      }

      // 附加按钮间距
      .button-blue,
      .button-red {
        margin: 5px 0 5px 5px;
      }
      // 最右侧质控靶值设定表格
      .tableBox {
        height: calc(100% - 40px);
      }
    }

    :deep(.result-table) {
      .number-right .vxe-cell {
        text-align: right;
        span {
          display: inline-block;
          width: calc(100% - 12px);
        }
      }
      .el-icon-warning {
        color: red;
      }
      .el-icon-warning-outline {
        color: $warning-color;
      }
      .el-icon-success {
        color: $success-color;
      }
      .zS2 {
        color: $warning-color;
      }
      .zS3 {
        color: $danger-color;
      }
      .zS-2 {
        color: $brand-color;
      }
      .zS-3 {
        color: #6600ff;
      }
    }
  }

  :deep(.drawerBulkModal) {
    inset: 50px 0 0 70px !important;
  }
  :deep(.el-drawer__body) {
    .iqcOutControl {
      width: 800px;
      // margin: 0 auto;
      transform: translateX(65%);
    }
  }
}
</style>
